#!/usr/bin/python

# yamp.py

import wx
import pygame
import threading
import time
import RepeatTimer

import numpy
import pyaudio
import fluidsynth

class Player(wx.Frame):
    def __init__(self, parent, id, title):

        wx.Frame.__init__(self, parent, id, title, size=(350, 300))
        panel = wx.Panel(self, -1)

        pnl1 = wx.Panel(self, -1)
        #pnl1.SetBackgroundColour(wx.BLACK)
        pnl2 = wx.Panel(self, -1 )

        menubar = wx.MenuBar()
        file = wx.Menu()
        help = wx.Menu()
        
        file.Append(101, '&Open', 'Open a MIDI file')
        file.Append(102, '&Exit', 'Quit application')
        
        help.Append(201, '&About', 'Credits')
        
        menubar.Append(file, '&File')
        menubar.Append(help, '&Help')
        
        self.SetMenuBar(menubar)
        
        self.Bind(wx.EVT_MENU, self.OnOpen, id = 101)
        self.Bind(wx.EVT_MENU, self.TimeToQuit, id = 102)
        self.Bind(wx.EVT_MENU, self.OnAbout, id = 201)
        
        slider1 = wx.Slider(pnl2, -1, 0, 0, 1000)
        
        play_bmp = wx.Bitmap('play.bmp')
        play_bmp.SetMask(wx.Mask(play_bmp, wx.Colour(255,0,255)))
        pause_bmp = wx.Bitmap('pause.bmp')
        pause_bmp.SetMask(wx.Mask(pause_bmp, wx.Colour(255,0,255)))
        start_bmp = wx.Bitmap('start.bmp')
        start_bmp.SetMask(wx.Mask(start_bmp, wx.Colour(255,0,255)))
        end_bmp = wx.Bitmap('end.bmp')
        end_bmp.SetMask(wx.Mask(end_bmp, wx.Colour(255,0,255)))
        
        pause = wx.BitmapButton(pnl2, -1, pause_bmp)
        play  = wx.BitmapButton(pnl2, -1, play_bmp)
        next  = wx.BitmapButton(pnl2, -1, start_bmp)
        prev  = wx.BitmapButton(pnl2, -1, end_bmp)
        #volume = wx.BitmapButton(pnl2, -1, )
        slider2 = wx.Slider(pnl2, -1, 0, 0, 100, size=(120, -1))

        self.music = "..\Latin.mid"
        self.music2 = "..\Documents\Downloads\LOCKET.MID.mid"
        
        self.paused = False
        self.curTime = 0.0

        freq = 44100    # audio CD quality
        bitsize = -16   # unsigned 16 bit
        channels = 4    # 1 is mono, 2 is stereo
        buffer = 1024   # number of samples
        pygame.mixer.init(freq, bitsize, channels, buffer)
        pygame.mixer.music.set_volume(0.8)
        
        self.Bind(wx.EVT_BUTTON, self.play_music, source=play)
        self.Bind(wx.EVT_BUTTON, self.toggle_pause, source=pause)

        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

        hbox1.Add(slider1, 1)
        hbox2.Add(pause)
        hbox2.Add(play, flag=wx.RIGHT, border=5)
        hbox2.Add(next, flag=wx.LEFT, border=5)
        hbox2.Add(prev)
        hbox2.Add((-1, -1), 1)
        #hbox2.Add(volume)
        hbox2.Add(slider2, flag=wx.TOP | wx.LEFT, border=5)

        vbox.Add(hbox1, flag=wx.EXPAND | wx.BOTTOM, border=10)
        vbox.Add(hbox2, 1, wx.EXPAND)
        pnl2.SetSizer(vbox)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(pnl1, 1, flag=wx.EXPAND)
        sizer.Add(pnl2, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)

        self.SetMinSize((350, 300))
        self.CreateStatusBar()
        self.SetSizer(sizer)

        self.Centre()
        self.Show()

    def play_music(self, event):
        """
        stream music with mixer.music module in blocking manner
        this will stream the sound from disk while playing
        """
        try:
            pygame.mixer.music.load(self.music)
            #print "Music file %s loaded!" % self.music
        except pygame.error:
            print "File %s not found! (%s)" % (self.music, pygame.get_error())
            return
        pygame.mixer.music.play()

        """sound = None
        try:
            sound = pygame.mixer.Sound(self.music2)
            #print "Music file %s loaded!" % self.music
            pygame.mixer.Channel(1).play(sound)
            print "success"
        except pygame.error:
            print "File %s not found! (%s)" % (self.music2, pygame.get_error())
            return"""
        
        
        # while pygame.mixer.music.get_busy():
            # check if playback has finished
            # clock.tick(30)

    """def fluid_play(self, event):
        #Plays a MIDI file using the python fluidaudio bindings
        
        pa = pyaudio.PyAudio() 
        strm = pa.open( 
            format = pyaudio.paInt16, 
            channels = 2, 
            rate = 44100, 
            output = True)
        
        s = []
        
        fl = fluidsynth.Synth()
        
        # Initial silence is 1 second 
        s = numpy.append(s, fl.get_samples(44100 * 1))

        sfid = fl.sfload("example.sf2") 
        fl.program_select(0, sfid, 0, 0)

        fl.noteon(0, 60, 30) 
        fl.noteon(0, 67, 30) 
        fl.noteon(0, 76, 30)
        
        # Chord is held for 2 seconds 
        s = numpy.append(s, fl.get_samples(44100 * 2))
        
        fl.noteoff(0, 60) 
        fl.noteoff(0, 67) 
        fl.noteoff(0, 76)
        
        # Decay of chord is held for 1 second 
        s = numpy.append(s, fl.get_samples(44100 * 1))
        
        fl.delete()
        
        samps = fluidsynth.raw_audio_string(s)
        
        print len(samps) 
        print 'Starting playback' 
        strm.write(samps)"""
        
    def toggle_pause(self, event):
        if self.paused:
            self.paused = False
            pygame.mixer.music.play(start=self.curTime)
        else:
            self.paused = True
            self.curTime = pygame.mixer.music.get_pos()
            pygame.mixer.music.stop()
    
    def OnAbout(self, event):
        dlg = wx.MessageDialog(self, "This sample program shows off\n"
                              "frames, menus, statusbars, and this\n"
                              "message dialog.",
                              "About Me", wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()

    def OnOpen(self, event):
        dlg = wx.FileDialog(self, message="Choose a MIDI", wildcard="All Files|*.*|MID files|*.mid|MIDDI files|*.midi") 
        dlg.ShowModal()
        dlg.Destroy()

    def TimeToQuit(self, event):
        self.Close(True)

    
            

app = wx.App()
Player(None, -1, 'Player')
app.MainLoop()
